package hnet

import (
	"fmt"
	"haruhi/hiface"
	"haruhi/utils"
	"net"
)

type Server struct {
	Name        string            // 名称
	IPVersion   string            // IP版本
	IP          string            // 监听IP
	Port        int               // 监听端口
	MsgHandler  hiface.IMsgHandle // 当前server消息管理模块，用来绑定msgId和对应的处理方法
	ConnManager hiface.IConnManager

	// 新增两个hook
	OnConnStart func(conn hiface.IConnection)
	OnConnStop  func(conn hiface.IConnection)
}

// // 定义当前用户的业务，之后进行优化  写死了,过失了
// func CallBackToClient(conn *net.TCPConn, data []byte, cnt int) error {
// 	// 回写业务
// 	fmt.Println("[Conn Handle] CallBackToClient...")

// 	if _, err := conn.Write(data[:cnt]); err != nil {
// 		fmt.Println("write back buf err ", err)
// 		return errors.New("CallBackToClient error")
// 	}
// 	return nil
// }

func (s *Server) Start() {
	fmt.Printf("[START] Server name: %s,listenner at IP: %s, Port %d is starting\n", s.Name, s.IP, s.Port)

	fmt.Printf("[haruhi] Version: %s, MaxConn: %d,  MaxPacketSize: %d\n",
		utils.GlobalObject.Version,
		utils.GlobalObject.MaxConn,
		utils.GlobalObject.MaxPacketSize)

	go func() {
		// 0.启动worker工作池机制
		s.MsgHandler.StartWorkerPool()

		// 1.获取TCP的address
		addr, err := net.ResolveTCPAddr(s.IPVersion, fmt.Sprintf("%s:%d", s.IP, s.Port))
		if err != nil {
			fmt.Println("resolve tcp addr error: ", err)
			return
		}
		// 2.监听服务器地址
		listenner, err := net.ListenTCP(s.IPVersion, addr)
		if err != nil {
			fmt.Println("listen ", s.IPVersion, " err ", err)
			return
		}
		fmt.Println("start haruhi server success, ", s.Name, " success, Listenning...")

		var cid uint32

		// 3.阻塞的等待客户端连接，处理客户端连接服务(读写)
		for {
			// 如果有客户端链接过来，阻塞会返回
			conn, err := listenner.AcceptTCP()
			if err != nil {
				fmt.Println("Accept err ", err)
				continue
			}

			if s.ConnManager.Len() >= utils.GlobalObject.MaxConn {
				conn.Close()
				continue
			}

			// 将处理新连接的业务方法和conn进行绑定，得到我们的连接模块
			dealConn := NewConnection(s, conn, cid, s.MsgHandler)
			cid++

			// 启动当前的业务处理
			go dealConn.Start()
		}
	}()

}

func (s *Server) Stop() {
	// TODO 服务停止和资源回收
	fmt.Println("[STOP] haruhi server, name ", s.Name)
	s.ConnManager.ClearConn()
}

func (s *Server) Serve() {
	// 启动服务
	s.Start()

	// TODO 做一些额外业务

	// 阻塞
	select {}
}

func (s *Server) AddRouter(msgId uint32, router hiface.IRouter) {
	s.MsgHandler.AddRouter(msgId, router)
	fmt.Println("Add Router Success!")
}

func (s *Server) GetConnManager() hiface.IConnManager {
	return s.ConnManager
}

func NewServer(name string) hiface.IServer {
	// 初始化全局配置文件
	utils.GlobalObject.Reload()

	s := &Server{
		Name:        utils.GlobalObject.Name,
		IPVersion:   "tcp4",
		IP:          utils.GlobalObject.Host,
		Port:        utils.GlobalObject.TcpPort,
		MsgHandler:  NewMsgHandle(),
		ConnManager: NewConnManager(),
	}
	return s
}

// 设置server连接创建时hook函数
func (s *Server) SetOnConnStart(hookFunc func(hiface.IConnection)) {
	s.OnConnStart = hookFunc
}

// 设置server连接断开时hook函数
func (s *Server) SetOnConnStop(hookFunc func(hiface.IConnection)) {
	s.OnConnStop = hookFunc
}

// 调用连接onConnStart hook函数
func (s *Server) CallOnConnStart(conn hiface.IConnection) {
	if s.OnConnStart != nil {
		fmt.Println("---> CallOnConnStart...")
		s.OnConnStart(conn)
	}
}

// 调用连接onConnStop hook函数
func (s *Server) CallOnConnStop(conn hiface.IConnection) {
	if s.OnConnStart != nil {
		fmt.Println("---> CallOnConnStop...")
		s.OnConnStop(conn)
	}
}
